package com.bailugansan.efficiencyboard.service.impl;

import com.bailugansan.efficiencyboard.constant.Constant;
import com.bailugansan.efficiencyboard.dao.TokenDao;
import com.bailugansan.efficiencyboard.dao.impl.TokenDaoImpl;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
import java.util.Map;

/**
 * @author BailuGansan
 */
@Service
public class JwtService {

    /**
     * key（按照签名算法的字节长度设置key）
     */
    private final static String SECRET_KEY = Constant.SignKey.SIGN_KEY.getKey();

    @Resource
    private TokenDao tokenDao;

    /**
     * 验证token
     * @param token
     * @return 0 验证成功，1、2、3、4、5 验证失败
     */
    public int verifyToken(String token) {
        try {
            Jwts.parser().setSigningKey(generateKey()).parseClaimsJws(token);
            return 0;
        } catch (ExpiredJwtException e) {
            e.printStackTrace();
            return 1;
        } catch (UnsupportedJwtException e) {
            e.printStackTrace();
            return 2;
        } catch (MalformedJwtException e) {
            e.printStackTrace();
            return 3;
        } catch (SignatureException e) {
            e.printStackTrace();
            return 4;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            return 5;
        }
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public Map<String, Object> parseToken(String token) {
        return Jwts.parser()  // 得到DefaultJwtParser
                .setSigningKey(generateKey()) // 设置签名密钥
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 生成安全密钥
     * @return
     */
    public Key generateKey() {
        return new SecretKeySpec(SECRET_KEY.getBytes(), SignatureAlgorithm.HS256.getJcaName());
    }

    /**
     * 判断token是否过期
     * @param tokenData
     * @return
     */
    public int isNotExpired(Map<String, Object> tokenData) {
        Long expiresAt = Long.parseLong(tokenData.get("exp").toString()) * 1000;
        if(new Date().getTime() - expiresAt < 0) {
            // token在有效期内
            return Constant.JwtToken.JWT_TOKEN_OK.getCode();
        } else {
            // token过期
            return Constant.JwtToken.JWT_TOKEN_EXPIRED.getCode();
        }
    }


    public boolean isEffective(Map<String, Object> tokenData, String token) {
        int code = isNotExpired(tokenData);
        if(Constant.JwtToken.JWT_TOKEN_OK.getCode() == code) {
//             TODO 数据库 简单判断uid和token是否匹配
//             if (data..) {
//             return true
//             }
//            TokenDao tokenDao = new TokenDaoImpl();

            String uid = tokenData.get("user_id").toString();
            boolean isEffective = tokenDao.isEffective(uid, token);
            return isEffective;
        }
        return false;
    }
}
